/*
*  contactlist.c - Contact list management functions
*  Copyright (c) 2005 Derek Ingrouville (dergro@users.sourceforge.net)
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Library General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdlib.h>
#include <string.h>

#include "contactlist.h"

MsnContactList *
msn_contactlist_new ()
{
	MsnContactList *clist;

	clist = g_new0 (MsnContactList, 1);

	/* The following also outputs a warning. */
	g_return_val_if_fail (clist != NULL, NULL);

	return clist;
}

MsnContactList *
msn_contactlist_from_syn (MsnCommand *syn)
{
	/* SYN ID TIMESTAMP1 TIMESTAMP2 #CONTACTS #GROUPS */
	MsnContactList *clist = NULL;

	/* TODO: timestamps */
	
	g_return_val_if_fail (syn != NULL, NULL);
	g_return_val_if_fail (syn->param_count > 0, NULL);

	clist = msn_contactlist_new ();
	clist->syn_num_contacts = atoi (syn->params [3]);

	return clist;
}

void
msn_clist_free (MsnContactList *clist)
{
	g_return_if_fail (clist != NULL);

	if (clist->groups != NULL) {
		MsnGroup *group = NULL;
		GList *list = clist->groups;

		while (list != NULL) {
			group = list->data;
			if (group == NULL)
				break;
			msn_group_free (group);
			list = g_list_next (list);
		}

		g_list_free (clist->groups);
		clist->groups = NULL;
	}

	clist->num_contacts = 0;
	clist->num_fl_contacts = 0;
	clist->num_groups = 0;
	clist->syn_num_contacts = 0;

	return;
}

int
msn_clist_add_contact (MsnContactList *clist, MsnContact *contact)
{
	MsnGroup *group = NULL;
	GList *cont_list = NULL;
	GList *group_list = NULL;

	g_return_val_if_fail (clist != NULL, -1);
	g_return_val_if_fail (contact != NULL, -1);

	clist->num_contacts++;

	/* Contact not on our FL */
	if (!msn_contact_on_forwardlist(contact)) {
		/* Free to avoid mem leak */
		msn_contact_free (contact);
		return 1;
	}

	list = contact->groups;
	while (list != NULL) {
		char *guid = NULL;
		guid = (char *) list->data;
		
		if (guid != NULL) {
			group = msn_clist_find_group (clist, guid);
			if (group == NULL)
				return -1;

			msn_group_add_contact (group, contact);
			clist->num_fl_contacts++;
		}
		list = g_list_next (list);
	}

	return 0;
}

int
msn_clist_add_group (MsnContactList *clist, MsnGroup *group)
{
	MsnGroup *tmp = NULL;

	g_return_val_if_fail (clist != NULL, -1);
	g_return_val_if_fail (group != NULL, -1);

	/* Check if we already have this group */
	tmp = msn_clist_find_group (clist, group->guid);
	if (tmp != NULL)
		return 0;

	clist->groups = g_list_append (clist->groups, group);
	clist->num_groups++;

	return 0;
}

int
msn_clist_remove_group (MsnContactList *clist, MsnGroup *group)
{
	g_return_val_if_fail (clist != NULL, -1);
	g_return_val_if_fail (group != NULL, -1);

	clist->groups = g_list_remove (clist->groups, group);
	clist->num_groups--;
	msn_group_free (group);

	return 0;
}

int
msn_clist_remove_contact (MsnContactList *clist, MsnContact *contact)
{
	MsnGroup *group = NULL;
	GList *list = NULL;

	g_return_val_if_fail (clist != NULL, -1);
	g_return_val_if_fail (contact != NULL, -1);

	list = contact->groups;
	while (list != NULL) {
		char *guid = 0;
		guid = (char *) list->data;

		group = msn_clist_find_group (clist, guid);
		if (group == NULL)
			return -1;

		msn_group_remove_contact (group, contact);
		list = g_list_next (list);
	}

	return 0;
}

MsnGroup *
msn_clist_find_group (MsnContactList *clist, const char *guid)
{
	MsnGroup *group = NULL;
	GList *list = NULL;

	g_return_val_if_fail (clist != NULL, NULL);

	list = g_list_first (clist->groups);

	while (list != NULL) {
		MsnGroup *tmp = (MsnGroup *) list->data;
		
		if (tmp == NULL)
			break;

		if (!strcmp (tmp->guid, guid)) {
			group = tmp;
			break;
		}

		list = g_list_next (list);
	}

	return group;
}

MsnGroup *
msn_clist_find_group_with_name (MsnContactList *clist, const char *name)
{
	MsnGroup *group = NULL;
	GList *list = NULL;

	g_return_val_if_fail (clist != NULL, NULL);

	list = g_list_first (clist->groups);

	while (list != NULL) {
		MsnGroup *tmp = (MsnGroup *) list->data;

		if (tmp == NULL)
			break;

		if (strncmp (tmp->name, name, strlen (tmp->name)) == 0) {
			group = tmp;
			break;
		}

		list = g_list_next (list);
	}

	return group;
}

MsnContact *
msn_clist_find_contact (MsnContactList *clist, const char *passport)
{
	MsnContact *contact = NULL;
	GList *list = NULL;

	g_return_val_if_fail (clist != NULL, NULL);

	list = g_list_first (clist->groups);

	while (list != NULL) {
		MsnGroup *group = (MsnGroup *) list->data;

		if (group == NULL)
			break;

		contact = msn_group_find_contact_from_passport (group, passport);

		if (contact != NULL)
			break;

		list = g_list_next (list);
	}

	return contact;
}

